package com.csyf.manager.service.impl;

import com.csyf.manager.channel.base.BaseTradeRequestVo;
import com.csyf.manager.channel.base.H5RequestVo;
import com.csyf.manager.channel.base.ServiceEnum;
import com.csyf.manager.channel.base.TrandeVo;
import com.csyf.manager.channel.cspay.CspayBiz;
import com.csyf.manager.channel.nmpay.NmPayBiz;
import com.csyf.manager.channel.pddPay.PddPayBiz;
import com.csyf.manager.channel.xiaojifu.XiaojifuBiz;
import com.csyf.manager.dao.SysTradeDao;
import com.csyf.manager.dao.SysTradeTypeDao;
import com.csyf.manager.entity.*;
import com.csyf.manager.service.OrderBiz;
import com.csyf.manager.service.SysMerchBiz;
import com.csyf.manager.service.SysChannelAttrBiz;
import com.csyf.manager.service.SysChannelBiz;
import com.csyf.manager.utils.NumberHelpler;
import com.csyf.manager.utils.TradeStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;

/**
 * @Author: Enzo
 * @Date: 2018/3/29 17:06
 */
@Slf4j
@Service
public class OrderBizImpl implements OrderBiz {

    @Autowired
    private SysTradeDao sysTradeDao;


    @Autowired
    private SysTradeTypeDao sysTradeTypeDao;


    @Autowired
    private SysMerchBiz sysMerchBiz;

    @Autowired
    private SysChannelBiz sysChannelBiz;

    @Autowired
    private SysChannelAttrBiz sysChannelAttrBiz;

    @Autowired
    private CspayBiz cspayBiz;

    @Autowired
    private NmPayBiz nmPayBiz;

    @Autowired
    private PddPayBiz pddPayBiz;

    @Autowired
    private XiaojifuBiz xiaojifuBiz;



    @Override
    public void orderSuccess(String orderNo, String srcCode, String message) {
        orderSuccess(orderNo, srcCode, message, null);
    }

    @Override
    public void orderSuccess(String orderNo, String srcCode, String message, String srcOrderNo) {
        SysTrade record = new SysTrade();
        record.setOutTradeNo(orderNo);

        SysTrade sysTrade1 = sysTradeDao.selectOne(record);


        SysTrade sysTrade = new SysTrade();
        sysTrade.setOutTradeNo(orderNo);
        if (null == sysTrade1.getPayTime()) {
            sysTrade.setPayTime(new Date());
        }
        if (null != srcOrderNo) {
            sysTrade.setSrcOrderNo(srcOrderNo);
        }
        sysTrade.setTradeStatus(TradeStatusEnum.TRADE_SUCCESS.toString());
        sysTrade.setSrcReason(srcCode + "|" + message);
        sysTradeDao.updateByPrimaryKeySelective(sysTrade);
    }

    @Override
    public String createOrder(TrandeVo vo) throws Exception {

        SysAgentChannel sysAgentChannel = insertData(vo);

        String s = sysAgentChannel.getMerchantNo();

        String payinfo = "";
        String service = vo.getService();
        ServiceEnum serviceEnum = ServiceEnum.valueOf(service);
        switch (serviceEnum) {
            case NM_ALI_H5:
                payinfo = nmPayBiz.dopay(vo, s);
                break;
            case PDD_ALI_SM:
            case PDD_WX_SM:
                payinfo = pddPayBiz.dopay(vo, s);
                break;
            case XJ_ALI_SM:
                payinfo = xiaojifuBiz.dopay(vo, s);
                break;
        }

        return payinfo;


    }


    @Override
    public void orderFaile(String orderNo, String srcCode, String message) {
        SysTrade sysTrade = new SysTrade();
        String spilt = "|";
        sysTrade.setOutTradeNo(orderNo);
        sysTrade.setTradeStatus(TradeStatusEnum.TRADE_FAILE.toString());
        if (message.contains(spilt)) {
            sysTrade.setSrcReason(message);
        } else {
            sysTrade.setSrcReason(srcCode + spilt + message);
        }
        sysTradeDao.updateByPrimaryKeySelective(sysTrade);
    }


    @Override
    public void processOrder(SysTrade sysTrade) {

        Date date = new Date();
        long InvalidTime = 1000 * 60 * 60;
        if (date.getTime() - sysTrade.getCreateTime().getTime() > InvalidTime) {

            SysTrade sysTrade1 = new SysTrade();
            sysTrade1.setTradeStatus(TradeStatusEnum.TRADE_FAILE.toString());
            sysTrade1.setSrcReason("9998|支付超时");
            sysTrade1.setOutTradeNo(sysTrade.getOutTradeNo());
            sysTradeDao.updateByPrimaryKeySelective(sysTrade1);
        }
    }

    /**
     * 异步通知状态修改(默认0-0 前面的0:次数,后面的0 状态)
     *
     * @param vo
     * @param downStatus
     */
    @Override
    public String updateNotifyStatus(SysTrade vo, String downStatus) {
        SysTrade sysTrade = new SysTrade();
        sysTrade.setOutTradeNo(vo.getOutTradeNo());
        sysTrade.setNotifyStatus("1-" + downStatus);
        sysTradeDao.updateByPrimaryKeySelective(sysTrade);
        return sysTrade.getNotifyStatus();
    }

//    @Override
//    public String createOrder(BaseTradeRequestVo vo) throws Exception {
//        SysAgentChannel sysAgentChannel = insertData(vo);
//
//
//        String payinfo = "";
//        H5RequestVo vo1 = (H5RequestVo) vo;
//        Map<String, String> map1 = wkPayBiz.h5WkPay(vo1, sysAgentChannel);
//        String h5WkPay = map1.get("formStr");
//        updateSrcOrderNo(vo.getOut_trade_no(), map1.get("flowId"));
//        return h5WkPay;
//    }


    private void updateSrcOrderNo(String orderNo, String srcOrderNo) {
        SysTrade example = new SysTrade();
        example.setOutTradeNo(orderNo);
        example.setSrcOrderNo(srcOrderNo);
        sysTradeDao.updateByPrimaryKeySelective(example);
    }


    private SysAgentChannel insertData(BaseTradeRequestVo vo) throws Exception {

        SysChannelAttr sysChannelAttr = sysChannelAttrBiz.findTradeByService(vo.getService());
        if (null == sysChannelAttr) {
            throw new IllegalArgumentException("全局通道未配置");
        }

        //判断是否小于最低金额
        log.info("判断是否小于最低金额:{}", sysChannelAttr.getMinMoney());
        BigDecimal total_fee = NumberHelpler.cent2money(vo.getTotal_fee());
        if (total_fee.compareTo(sysChannelAttr.getMinMoney()) < 0) {
            throw new IllegalArgumentException("交易金额小于最低金额 :" + sysChannelAttr.getMinMoney());
        }

        //判断是否大于最高金额
        log.info("判断是否大于最高金额{}", sysChannelAttr.getMaxMoney());
        if (total_fee.compareTo(sysChannelAttr.getMaxMoney()) > 0) {
            throw new IllegalArgumentException("交易金额超出交易限制 :" + sysChannelAttr.getMaxMoney());
        }

        SysTrade example = new SysTrade();
        example.setOutTradeNo(vo.getOut_trade_no());
        int count = sysTradeDao.selectCount(example);
        if (count > 0) {
            throw new IllegalArgumentException("订单号已存在");
        }

        SysMerchant sysAgent = sysMerchBiz.queryAgentByMerchantNo(vo.getMch_id());


        SysTrade sysTrade = new SysTrade();
        sysTrade.setOutTradeNo(vo.getOut_trade_no());
        sysTrade.setMchId(vo.getMch_id());
        sysTrade.setAgentId(sysAgent.getId());
        sysTrade.setAgentName(sysAgent.getMerchName());
        sysTrade.setTradeStatus(TradeStatusEnum.WAIT_BUYER_PAY.toString());


        if (vo instanceof TrandeVo) {
            TrandeVo vo1 = (TrandeVo) vo;
            sysTrade.setNotifyUrl(vo1.getNotify_url());
        } else if (vo instanceof H5RequestVo) {
            H5RequestVo vo2 = (H5RequestVo) vo;
            sysTrade.setNotifyUrl(vo2.getNotify_url());
        }

        sysTrade.setTotalFee(NumberHelpler.cent2money(vo.getTotal_fee()));
        sysTrade.setServiceType(vo.getService());
        sysTrade.setCreateTime(new Date());

        //选择上游通道的商户号
        SysAgentChannel sysAgentChannel = sysChannelBiz.handleMchant(vo.getMch_id(), vo.getService());

        SysTradeType sysTradeType = new SysTradeType();
        sysTradeType.setMch_id(vo.getMch_id());
        sysTradeType.setTradeType(vo.getService());
        SysTradeType tradeType = sysTradeTypeDao.selectOne(sysTradeType);

        BigDecimal multiply = NumberHelpler.multiply(sysTrade.getTotalFee(), tradeType.getRate());
        BigDecimal sysprofit = BigDecimal.ZERO;
        if (null != sysAgentChannel.getCostRate()) {
            sysprofit = NumberHelpler.multiply(sysTrade.getTotalFee(), sysAgentChannel.getCostRate());
        } else {
            log.warn("[{}] 没有配置好费率", sysAgentChannel.getMerchantNo());
        }


        //最低手续费
        BigDecimal downfree = sysChannelAttr.getMinTip();


        multiply = multiply.compareTo(downfree) < 0 ? downfree : multiply;
        sysprofit = sysprofit.compareTo(downfree) < 0 ? downfree : sysprofit;

        //总收益= 交易金额-手续费
        BigDecimal profit = multiply.compareTo(sysTrade.getTotalFee()) > 0 ? BigDecimal.ZERO : NumberHelpler.subtract(sysTrade.getTotalFee(), multiply);
        BigDecimal myprofit = multiply.compareTo(sysTrade.getTotalFee()) > 0 ? BigDecimal.ZERO : NumberHelpler.subtract(sysTrade.getTotalFee(), sysprofit);

        // 商户结算金额小数点后两位直接舍弃
        sysTrade.setProfit(profit.setScale(2, BigDecimal.ROUND_DOWN));
        sysTrade.setCostprofit(myprofit.subtract(profit).setScale(2, BigDecimal.ROUND_HALF_UP));

        sysTrade.setSrcMchId(sysAgentChannel.getMerchantNo());
        sysTradeDao.insertSelective(sysTrade);
        return sysAgentChannel;
    }


}
